package businessDelegate;

import interfaces.InterfaceRemota;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.List;

import javax.naming.CommunicationException;
//import javax.swing.JOptionPane;














import org.apache.jasper.tagplugins.jstl.core.ForEach;
import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;

import dto.CargaDTO;
import dto.ClienteDTO;
import dto.EmpresaDTO;
import dto.EnvioDTO;
//import dto.UbicacionDTO;
import dto.ParticularDTO;
import dto.ProductoDTO;
import dto.RemitoDTO;
import dto.SucursalDTO;
import dto.TamanioDTO;
import dto.TipoTransporteDTO;
import dto.VehiculoDTO;
//import dto.*;

public class Delegate {

	private static Delegate instancia;
	private InterfaceRemota referenciaRemota;

	private Delegate () throws CommunicationException, RemoteException, NotBoundException
	{
		conexionRemota();
	}
	
	private void conexionRemota() throws CommunicationException, RemoteException, NotBoundException
	{
		try 
		{
			final String IP = "127.0.0.1";
		    final Registry registry = LocateRegistry.getRegistry(IP, Registry.REGISTRY_PORT);
		    final String[] enlacesRemotos = registry.list();
		    
		    for (String enlace : enlacesRemotos) 
		    {
		    	referenciaRemota = (InterfaceRemota) Naming.lookup(enlace);
		    }
			
		} catch (MalformedURLException e) 
		{
			throw new CommunicationException("Error al establecer la conexion");
		}
	}

	public static Delegate getInstancia() throws CommunicationException, RemoteException, NotBoundException
	{
		if(instancia==null)
			instancia=new Delegate();
		return instancia;
	}
	
	
	public boolean altaCliente(ClienteDTO cliente)
	{
		try {
			referenciaRemota.saveCliente(cliente);
			return true;
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
		
	}
	
	public boolean saveParticular (ParticularDTO particular) throws RemoteException 
	{
		try {
			referenciaRemota.agregarParticular(particular);			
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}		 
		 return true;
	}
	
	public boolean saveEmpresa (EmpresaDTO empresa) throws RemoteException 
	{
		try {
			referenciaRemota.agregarEmpresa(empresa);			
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}		 
		 return true;
	}
	
	
	
	public ParticularDTO getParticular(ParticularDTO particular) {
		//recibe un particularDTO con el DNI cargado, y devuelve el DTO con todos los datos si es que existe. 
		dto.ParticularDTO resultado = new ParticularDTO ();
		try {
			resultado = referenciaRemota.LoadParticular(particular);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (resultado==null)
			return particular;
		else
			return resultado;
		//resultado.setDNI(particular.getDNI());		
	}
	
	public EmpresaDTO getEmpresa(EmpresaDTO empresa) {
		//recibe un EmpresaDTO con el CUIT cargado, y devuelve el DTO con todos los datos si es que existe.
		EmpresaDTO resultado = new EmpresaDTO ();
		try {
			resultado = referenciaRemota.loadEmpresa(empresa);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		if (resultado==null)
			return empresa;
		else
			return resultado;		
		//resultado.setCUIT(empresa.getCUIT());
		
	}
	
	public boolean actualizarCliente ( ClienteDTO cliente) throws RemoteException {
		//recibe un particular con todos los datos para grabarlo en el negocio. el particular puede o no existir.		
		//boolean resultado = 
			
		//return referenciaRemota.saveCliente(cliente);
		return true;
	}
	
	public List<VehiculoDTO> getVehiculosSinMantenimiento() throws RemoteException
	{
		return referenciaRemota.vehiculosSinMantenimiento();
	}
	
	public boolean actualizarVehiculosMantenimiento (List <String> vehiculos) throws RemoteException {
		
		boolean resultado = referenciaRemota.updateMantenimientoVehiculos(vehiculos);		
		return resultado;
	}
	
	public List <TamanioDTO> getTamanios () throws RemoteException {		
		List <TamanioDTO> tamanios = referenciaRemota.loadTamanios();
		return tamanios;
	}
	
	public List <SucursalDTO> getSucursales () throws RemoteException {
		List <SucursalDTO> sucursales = referenciaRemota.loadSucursales();
		return sucursales;
	}

	public List <TipoTransporteDTO> getTipoTransporte () throws RemoteException {
		List <TipoTransporteDTO> tipos = referenciaRemota.loadTipos();
		return tipos;
		
	}
	
	public List <EmpresaDTO> getEmpresaList () throws RemoteException {
		List <EmpresaDTO> empresas = referenciaRemota.getEmpresaList();
		return empresas;
		
	}
	
	public List <ParticularDTO> getParticularList () throws RemoteException {
		List <ParticularDTO> particulares = referenciaRemota.getParticularList();
		return particulares;
		
	}

	public List<ClienteDTO> getClientes() throws RemoteException{
		// TODO Auto-generated method stub
		List < ClienteDTO> clientes = new ArrayList <ClienteDTO> () ;
		List <ParticularDTO> particulares;
		List <EmpresaDTO> empresas;		
		
		empresas = referenciaRemota.getEmpresaList();
		particulares = referenciaRemota.getParticularList();
		
		for (EmpresaDTO empresa : empresas) {
			clientes.add(empresa);
		}
		
		for (ParticularDTO particular : particulares) {
			clientes.add(particular);
		}
		
		return clientes;
	}

	public List<CargaDTO> getCargasPendientes() throws RemoteException {
		// TODO Auto-generated method stub
		List <CargaDTO> paquetes;
		//paquetes = referenciaRemota.loadCargasPendientes();
		//return paquetes;
		return null;
	}

	public List<CargaDTO> getCargaPendienteFacturarParticular(String numero) {
		// TODO Auto-generated method stub
		List <CargaDTO> paquetes;
		//paquetes = referenciaRemota.loadCargaPendienteFacParticular(numero);
		return null;
	}

	public List<CargaDTO> getCargaPendienteFacturarEmpresa(String numero) {
		// TODO Auto-generated method stub
		List <CargaDTO> paquetes;
		//paquetes = referenciaRemota.loadCargaPendienteFacEmpresa(numero);
		return null;
	}

	public List<EnvioDTO> getEnviosPendienteDePago(EmpresaDTO empresa) throws RemoteException {
		// TODO Auto-generated method stub
		List <EnvioDTO> enviosPendientesDePago = referenciaRemota.enviosPendienteDePago(empresa);
		return enviosPendientesDePago;
	}

	public void saveCarga(CargaDTO carga) throws RemoteException  {
		referenciaRemota.saveCarga(carga);
		// TODO Auto-generated method stub		
	}
	
	public ClienteDTO getClienteById(Integer id) throws RemoteException {
		ClienteDTO cliente  = referenciaRemota.LoadCliente(id);
		return cliente;
	}
	
	public TamanioDTO getTamanioById(Integer id) throws RemoteException {
		TamanioDTO tamanio = referenciaRemota.loadTamanio(id);
		return tamanio;
	}
	
	public boolean saveProductoEmpresa (ProductoDTO producto) throws RemoteException 
	{
		try {
			referenciaRemota.agregarProductoEmpresa(producto);	
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}		 
		 return true;
	}
	
	public RemitoDTO getRemitoById (String Id) {
		
		int identifier = Integer.parseInt(Id);
		RemitoDTO remito = new RemitoDTO();
		try {
			remito = referenciaRemota.obtenerRemito(identifier);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return remito;
	}
	
	
	public boolean pagarFactura(RemitoDTO remito)
	{
		try{
			referenciaRemota.pagarFactura(remito);
			//referenciaRemota.pagarFactura(remito, valor);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}		 
		return true;	
	}

}
